package com.test.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.hustcad.plm.basic.entity.TyplmObjectAliasDO;
import com.hustcad.plm.basic.service.TyplmObjectAliasService;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.basic.util.TyplmLoggerUtil;
import com.hustcad.plm.basic.util.TyplmPinYinUtil;
import com.hustcad.plm.pdm.folder.service.TyplmCabinetService;
import com.hustcad.plm.pdm.user.model.constant.UserErrorCodeEnum;
import com.hustcad.plm.pdm.user.model.dto.PdmUserDTO;
import com.hustcad.plm.pdm.user.model.entity.PdmUser;
import com.hustcad.plm.pdm.user.service.TyplmMemberLinkService;
import com.hustcad.plm.pdm.user.service.TyplmOrgContainerService;
import com.hustcad.plm.pdm.user.service.TyplmOrgService;
import com.hustcad.plm.pdm.user.service.TyplmPrincipalService;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.pdm.user.service.impl.organization.PdmUserServiceImpl;
import com.hustcad.plm.pdm.user.service.organization.PdmUserService;
import com.hustcad.plm.pdm.user.util.TyplmUserDealUtil;
import com.ty.basic.entity.org.OrgContainerDO;
import com.ty.basic.entity.org.OrgDO;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.exception.message.SystemErrorCodeEnum;
import com.ty.basic.handler.exceptionhandler.exception.ResponseCodeEnum;
import com.ty.basic.handler.exceptionhandler.exception.TyException;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Service
@Primary
public class CustomPdmUserServiceImpl extends PdmUserServiceImpl implements PdmUserService {
    private static final Logger log = LoggerFactory.getLogger(CustomPdmUserServiceImpl.class);
    @Resource
    private TyplmOrgService typlmOrgService;
    @Autowired
    private TyplmUserService typlmUserService;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private TyplmPrincipalService typlmPrincipalService;
    @Resource
    private TyplmObjectAliasService typlmObjectAliasService;
    @Resource
    private TyplmCabinetService typlmCabinetService;
    @Resource
    private TyplmMemberLinkService typlmMemberLinkService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private TyplmOrgContainerService typlmOrgContainerService;

    @Override
    public PdmUserDTO createUserInOrg(PdmUserDTO user) {
        TyplmEntityBaseUtil.checkParamNotNull(user.getOrgOid(), "orgOid");
        TyplmLoggerUtil.debug(log, () -> "createUserInOrg的入参PdmUserDTO为==>【{}】", () -> new Object[]{JSON.toJSONString(user)});
        OrgDO org = this.typlmOrgService.queryOrgById(user.getOrgOid());
        if (org == null) {
            throw new TyException(Collections.singletonList(new TyException(ResponseCodeEnum.BIZ_OBJECT_NOT_FOUND, new String[]{TyplmEntityBaseUtil.getOtypeDisplayName("ty.inteplm.org.CTyOrg") + ":" + user.getOrgOid()})));
        } else {
            return this.createUserInOrg(org, this.getOrgContainerByOrg(org), user);
        }
    }

    //使用父类同名方法重写父类方法，取消校验特殊字符逻辑
    private PdmUserDTO createUserInOrg(OrgDO org, OrgContainerDO containerDO, PdmUserDTO user) {
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> child createUserInOrg");
        TyplmEntityBaseUtil.checkParamNotNull(org, "Org");
        TyplmEntityBaseUtil.checkParamNotNull(containerDO, "OrgContainer");
        TyplmUserDealUtil.checkName(user.getAccount());
        this.checkFullName(user.getUsername());
        if (StringUtils.isNotBlank(user.getPassword())) {
            user.setPassword(SecureUtil.sha256(user.getPassword()));
        }

        if (StringUtils.isBlank(user.getLang())) {
            user.setLang("zh_CN");
        }

        user.setStatus("1");
        if (this.typlmUserService.checkName((BigInteger) null, user.getAccount())) {
            throw SystemErrorCodeEnum.NO_DEFINE_VALID_EXCEPTION.getException(new Object[]{"用户已经存在"});
        } else {
            BigInteger userOid = this.snowflakeIdComponent.getInstance().nextId();
            user.setOid(userOid.toString());
            user.setOtype("ty.inteplm.org.CTyUser");
            PdmUser pdmUser = TyplmUserDealUtil.coverUserToDo(user);
            this.setDefaultFields(user, pdmUser);
            pdmUser.setDomainoid(containerDO.getDomainoid());
            pdmUser.setDomainotype(containerDO.getDomainotype());
            pdmUser.setContaineroid(containerDO.getOid());
            pdmUser.setContainerotype(containerDO.getOtype());
            this.typlmPrincipalService.checkPrincipal(pdmUser);
            List<TyplmObjectAliasDO> pinYinDOList = new ArrayList();
            if (Strings.isNotBlank(pdmUser.getName())) {
                String namePinyin = TyplmPinYinUtil.getPinyinByChinese(pdmUser.getName());
                pdmUser.setNamepinyin(namePinyin);
                List<TyplmObjectAliasDO> namepinYinDOList = this.typlmObjectAliasService.batchDealTyplmPinYinDO(userOid,
                                                                                                                "ty.inteplm.org.CTyUser",
                                                                                                                "ty_user;name",
                                                                                                                namePinyin);
                if (CollUtil.isNotEmpty(namepinYinDOList)) {
                    pinYinDOList.addAll(namepinYinDOList);
                }
            }

            if (Strings.isNotBlank(pdmUser.getFullname())) {
                String fullnamePinyin = TyplmPinYinUtil.getPinyinByChinese(pdmUser.getFullname());
                pdmUser.setFullnamepinyin(fullnamePinyin);
                List<TyplmObjectAliasDO> fullNamepinYinDOList = this.typlmObjectAliasService.batchDealTyplmPinYinDO(
                        userOid, "ty.inteplm.org.CTyUser", "ty_user;fullname", fullnamePinyin);
                if (CollUtil.isNotEmpty(fullNamepinYinDOList)) {
                    pinYinDOList.addAll(fullNamepinYinDOList);
                }
            }

            user = this.coverUserToDto(this.createuserByDO(pdmUser), new PdmUserDTO());
            if (CollUtil.isNotEmpty(pinYinDOList)) {
                this.typlmObjectAliasService.batchInsertPinyin(pinYinDOList);
            }

            UserDO userDO = this.typlmUserService.queryUserByKey(pdmUser.getOid());
            this.typlmCabinetService.createPersonalCabinetAndSubfolder(Collections.singletonList(userDO));
            if (org.getOid().equals(containerDO.getOrgoid())) {
                this.typlmMemberLinkService.addParentForPrincipal(Collections.singletonList(org), userDO);
            } else {
                OrgDO containerOrg = this.typlmOrgService.queryOrgByKey(containerDO.getOrgoid());
                this.typlmMemberLinkService.addParentForPrincipal(Arrays.asList(org, containerOrg), userDO);
            }

            if (TyAccountContext.isDebug()) {
                log.info("createUserInOrg的出参user为<==【{}】", JSON.toJSONString(user));
            }

            return user;
        }
    }

    private void setDefaultFields(PdmUserDTO user, PdmUser pdmUser) {
        if (null == user.getTele() || "".equals(user.getTele())) {
            pdmUser.setTelephone((String) null);
        }

        if (null == user.getBirthday() || "".equals(user.getBirthday())) {
            pdmUser.setExt2((String) null);
        }

        if (null == user.getEmail() || "".equals(user.getEmail())) {
            pdmUser.setEmail((String) null);
        }

        if (StringUtils.isNotBlank(pdmUser.getPassword())) {
            pdmUser.setPassword(this.passwordEncoder.encode(pdmUser.getPassword()));
        }

    }

    private void checkFullName(String fullname) {
        TyplmEntityBaseUtil.checkParamNotNull(fullname, "fullname");
        if (fullname.length() > 64) {
            throw UserErrorCodeEnum.USER_FULLNAME_EXCEED.getException(new Object[0]);
        }
    }

    private OrgContainerDO getOrgContainerByOrg(OrgDO org) {
        OrgContainerDO containerDO = null;
        if ("ty.inteplm.domain.CTySiteContainer".equals(org.getContainerotype())) {
            containerDO = this.typlmOrgContainerService.queryOrgContainerByOrg(org.getOid(), org.getOtype());
        } else {
            containerDO = this.typlmOrgContainerService.queryOrgContainerByOid(org.getContaineroid());
        }

        if (containerDO == null) {
            throw new TyException(Collections.singletonList(new TyException(ResponseCodeEnum.BIZ_OBJECT_NOT_FOUND, new String[]{"OrgContainer"})));
        } else {
            if (TyAccountContext.isDebug()) {
                log.info("getOrgContainerByOrg的出参containerDO为<==【{}】", JSON.toJSONString(containerDO));
            }

            return containerDO;
        }
    }
}
